package com.easy.util;

import io.jsonwebtoken.*;
import io.jsonwebtoken.io.Decoders;
import io.jsonwebtoken.security.Keys;
import io.jsonwebtoken.security.SecurityException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.crypto.SecretKey;
import java.util.Date;

@Component
public class JwtUtils {
    //日志记录器
    private static final Logger logger = LoggerFactory.getLogger(JwtUtils.class);

    //保存签名/验签用的对称密钥（不可变，线程安全）
    private final SecretKey secretKey;
    // 生成符合HS512算法要求的密钥（512位/64字节）
    //private static final SecretKey SECRET_KEY = Keys.secretKeyFor(SignatureAlgorithm.HS512);

    //可随机生成一把 HS512 密钥；但随机密钥不可跨实例共享（重启或多实例会导致旧 token 无法验证），所以实际改为从配置读取
    // 令牌过期时间（2小时）
    private static final long EXPIRATION = 2 * 60 * 60 * 1000;

    // 构造函数中基于配置初始化密钥（不会为null）从配置中加载密钥
    public JwtUtils(@Value("${jwt.secret}") String secretBase64) {
        if (secretBase64 == null || secretBase64.isBlank()) {
            throw new IllegalStateException("缺少 jwt.secret 配置");
        }
        //将 Base64 字符串解码为字节数组
        byte[] keyBytes = Decoders.BASE64.decode(secretBase64);
        this.secretKey = Keys.hmacShaKeyFor(keyBytes); // HS512 需要足够长的key
    }

    //生成 Token
    public String generateToken(Integer userId,String role) {
        try {
            Date now = new Date();
            Date expirationDate = new Date(now.getTime() + EXPIRATION);
            System.out.println("expirationDate");
            System.out.println(expirationDate);

            String token = Jwts.builder()
                    .setSubject(userId.toString()) //设置用户ID为主体
                    .claim("role",role)
                    .setIssuedAt(now)  //签发时间
                    .setExpiration(expirationDate) //过期时间
                    .signWith(secretKey, SignatureAlgorithm.HS512) // 使用HS512和密钥签名
                    .compact();

            logger.info("为用户ID: {} 生成Token成功", userId);
            return token;
        } catch (Exception e) {
            logger.error("Token生成失败: {}", e.getMessage());
            throw new RuntimeException("Token生成失败: " + e.getMessage());
        }
    }
//从Token解析用户ID
    public Integer getUserIdFromToken(String token) {
//        if (token == null || token.isEmpty()) {
//            throw new RuntimeException("JWT String argument cannot be null or empty");
//        }
        System.out.println("getUserIdFromToken"+token);
        try {
            if (token.startsWith("Bearer ")) {
                token = token.substring(7); // 去除 "Bearer " 前缀
            }
            Claims claims = Jwts.parserBuilder()
                    .setSigningKey(secretKey)
                    .build()
                    .parseClaimsJws(token)//验证Token的签名是否正确
                    .getBody();

            return Integer.parseInt(claims.getSubject());//成功后从claims中取出用户ID
        } catch (ExpiredJwtException e) {
            logger.warn("Token已过期: {}", e.getMessage());
            throw new JwtException("Token已过期");
        } catch (SecurityException | MalformedJwtException e) {
            logger.error("Token签名无效: {}", e.getMessage());
            throw new JwtException("无效的Token签名");
        } catch (Exception e) {
            logger.error("从Token中解析用户ID失败: {}", e.getMessage());
            throw new RuntimeException("无效的Token");
        }
    }
    //获取role
    public String getRoleFromToken(String token) {
        Claims claims = Jwts.parser()
                .setSigningKey(secretKey)
                .parseClaimsJws(token)
                .getBody();
        return claims.get("role", String.class);  // 获取 token 中存储的角色信息
    }

    //验证Token
    public boolean validateToken(String token) {
        try {
            Jwts.parserBuilder()
                    .setSigningKey(secretKey)
                    .build()
                    .parseClaimsJws(token);
            logger.info("Token验证通过");
            return true;
        } catch (ExpiredJwtException e) {
            logger.warn("Token已过期: {}", e.getMessage());
        } catch (UnsupportedJwtException e) {
            logger.error("不支持的Token格式: {}", e.getMessage());
        } catch (MalformedJwtException e) {
            logger.error("Token格式错误: {}", e.getMessage());
        } catch (SecurityException e) {
            logger.error("Token签名验证失败: {}", e.getMessage());
        } catch (IllegalArgumentException e) {
            logger.error("Token参数为空: {}", e.getMessage());
        } catch (Exception e) {
            logger.error("Token验证失败: {}", e.getMessage());
        }
        return false;
    }
}